using System;
using System.Collections.ObjectModel;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;
using MongoDB.Bson.Serialization;

namespace Charisma.MongoDb.Linq.Expressions
{
  internal sealed class EntityExpression : MongoExpression
  {
    public Expression Expression { get; private set; }
    public BsonClassMap MetaType { get; private set; }

    public override bool CanReduce
    {
      get { return true; }
    }

    public override Expression Reduce()
    {
      return Expression;
    }

    protected override Expression Accept(ExpressionVisitor visitor)
    {
      var mongoVisitor = visitor as MongoExpressionVisitor;
      if (mongoVisitor == null)
        return this;
      return mongoVisitor.VisitEntity(this);
    }

    public override string ToString()
    {
      return Type.Name;
    }

    public EntityExpression(Expression expression, BsonClassMap metaType)
      : base(MongoExpressionType.Entity, expression.Type)
    {
      Contract.Requires(expression != null);
      Contract.Requires(expression.Type != null);
      Contract.Requires(metaType != null);
      
      Expression = expression;
      MetaType = metaType;
    }
  }
}